package com.boss.salary.controller;

import com.boss.api.dto.ApiResultDTO;
import com.boss.common.base.BasicinfoBaseController;
import com.boss.common.entity.PageDTO;
import com.boss.common.util.PageUtils;
import com.boss.framework.dto.PaginationDTO;
import com.boss.framework.exception.AppRuntimeException;
import com.boss.salary.entity.OperrateLogs;
import com.boss.salary.service.IGenerateBankDataService;
import com.boss.salary.service.IOperrateLogsService;
import com.boss.salary.vo.SalaryDataVo;
import com.boss.sys.ca.user.dto.UserDTO;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletResponse;
import java.io.OutputStream;
import java.nio.charset.StandardCharsets;
import java.util.List;
import java.util.Map;

@RestController
@RequestMapping("/generateBankDataController")
public class GenerateBankDataController extends BasicinfoBaseController {

    private final static Logger logger = LoggerFactory.getLogger(GenerateSalaryDataController.class);

    @Autowired
    private IGenerateBankDataService generateBankDataService;

    @Autowired
    private IOperrateLogsService iOperrateLogsService;

    @GetMapping("/queryGenerateBankDataPage")
    public ApiResultDTO queryGenerateBankDataPage(@RequestHeader("X-Token") String tokenid,
                                                  @RequestParam("page") String page,
                                                  @RequestParam("limit") String limit,
                                                  @RequestParam Map<String,Object> queryForm){
        try {
            UserDTO userDTO = getUser(tokenid);
            PaginationDTO paginationDTO = PageUtils.buildPaginationDTOPage(page,limit);
            PageDTO<SalaryDataVo> pageDTO = generateBankDataService.getGenerateBankDataPage(paginationDTO, queryForm, userDTO);
            return ApiResultDTO.success(pageDTO);
        } catch (Exception e) {
            logger.error(e.getMessage(), e);
            return ApiResultDTO.error(ERROR_RSCODE, "查询数据异常");
        }
    }

    @GetMapping("/queryPersonSalaryInfoPage")
    public ApiResultDTO queryPersonSalaryInfoPage(@RequestHeader("X-Token") String tokenId,
                                                  @RequestParam("page") String page,
                                                  @RequestParam("limit") String limit,
                                                  @RequestParam Map<String, Object> queryForm){
        try {
            UserDTO userDTO = getUser(tokenId);
            PaginationDTO paginationDTO = PageUtils.buildPaginationDTOPage(page,limit);
            PageDTO<Map<String, Object>> pageDTO = generateBankDataService.getPersonSalaryInfoPage(userDTO,paginationDTO, queryForm);
            return ApiResultDTO.success(pageDTO);
        } catch (AppRuntimeException e) {
            logger.error(e.getMessage(), e);
            return ApiResultDTO.error(ERROR_RSCODE, e.getMessage());
        } catch (Exception e) {
            logger.error(e.getMessage(), e);
            return ApiResultDTO.error(ERROR_RSCODE, e.getMessage());
        }
    }

    @PostMapping("/uploadBankData")
    public ApiResultDTO uploadBankData(@RequestHeader("X-Token") String tokenId,@RequestBody Map<String,Object> queryForm){
        try {
            UserDTO userDto = getUser(tokenId);
            //添加操作日志
            OperrateLogs operrateLogs= new OperrateLogs();
            operrateLogs.setMofDivCode(userDto.getProvince());
            operrateLogs.setTokenId(tokenId);
            operrateLogs.setUserAgencyId(userDto.getAgency());
            operrateLogs.setUeserName(userDto.getName());
            operrateLogs.setOperateName("生成工资数据--生成银行数据--上传");
            iOperrateLogsService.saveOperrateLogs(operrateLogs);

            String province = getUser(tokenId).getProvince();
            generateBankDataService.uploadBankData(province,queryForm.get("salaCardBank").toString());
            return ApiResultDTO.success();
        } catch (Exception e) {
            logger.error(e.getMessage(), e);
            return ApiResultDTO.error(ERROR_RSCODE, "上传失败");
        }
    }

    @PostMapping("/regenerateBankData")
    public ApiResultDTO regenerateBankData(@RequestHeader("X-Token") String tokenId,@RequestBody Map<String,Object> queryForm){
        try {
            UserDTO userDto = getUser(tokenId);
            //添加操作日志
            OperrateLogs operrateLogs= new OperrateLogs();
            operrateLogs.setMofDivCode(userDto.getProvince());
            operrateLogs.setTokenId(tokenId);
            operrateLogs.setUserAgencyId(userDto.getAgency());
            operrateLogs.setUeserName(userDto.getName());
            operrateLogs.setOperateName("生成工资数据--生成银行数据--撤销上传");
            iOperrateLogsService.saveOperrateLogs(operrateLogs);

            String province = getUser(tokenId).getProvince();
            generateBankDataService.regenerateBankData(province,queryForm.get("salaCardBank").toString());
            return ApiResultDTO.success();
        } catch (Exception e) {
            logger.error(e.getMessage(), e);
            return ApiResultDTO.error(ERROR_RSCODE, "重新生成失败");
        }
    }

    @PostMapping("/ungenerateBankData")
    public ApiResultDTO ungenerateBankData(@RequestHeader("X-Token") String tokenId,@RequestBody Map<String,Object> queryForm){
        try {
            UserDTO userDto = getUser(tokenId);
            //添加操作日志
            OperrateLogs operrateLogs= new OperrateLogs();
            operrateLogs.setMofDivCode(userDto.getProvince());
            operrateLogs.setTokenId(tokenId);
            operrateLogs.setUserAgencyId(userDto.getAgency());
            operrateLogs.setUeserName(userDto.getName());
            operrateLogs.setOperateName("生成工资数据--生成银行数据--撤销上传");
            iOperrateLogsService.saveOperrateLogs(operrateLogs);

            String province = getUser(tokenId).getProvince();
            generateBankDataService.ungenerateBankData(province,queryForm.get("salaCardBank").toString());
            return ApiResultDTO.success();
        } catch (Exception e) {
            logger.error(e.getMessage(), e);
            return ApiResultDTO.error(ERROR_RSCODE, "重新生成失败");
        }
    }

    /**
     * 生成银行数据
     */
    @PostMapping("/generateBankData")
    public ApiResultDTO generateBankData(@RequestHeader("X-Token") String tokenId,@RequestBody Map<String,Object> queryForm){
        try {
            UserDTO userDto = getUser(tokenId);
            //添加操作日志
            OperrateLogs operrateLogs= new OperrateLogs();
            operrateLogs.setMofDivCode(userDto.getProvince());
            operrateLogs.setTokenId(tokenId);
            operrateLogs.setUserAgencyId(userDto.getAgency());
            operrateLogs.setUeserName(userDto.getName());
            operrateLogs.setOperateName("生成工资数据--生成银行数据--生成银行数据");
            iOperrateLogsService.saveOperrateLogs(operrateLogs);

            if(StringUtils.isEmpty(queryForm.get("salaCardBank"))){//若未传银行参数，择不显示任何内容
                return ApiResultDTO.error(ERROR_RSCODE, "请选择银行！");
            }
            String province = getUser(tokenId).getProvince();
            queryForm.put("province",province);
            generateBankDataService.generateBankData(province,queryForm);
            return ApiResultDTO.success();
        } catch (Exception e) {
            logger.error(e.getMessage(), e);
            return ApiResultDTO.error(ERROR_RSCODE, "生成失败");
        }
    }

    /**
     * 验证文件生成和上传状态
     * @return
     */
    @GetMapping("/verifyFileState")
    public ApiResultDTO verifyFileState(@RequestHeader("X-Token") String tokenId){
        try {
            String province = getUser(tokenId).getProvince();
            boolean state = generateBankDataService.verifyFileState(province);
            return ApiResultDTO.success(state);
        } catch (AppRuntimeException e) {
            logger.error(e.getMessage(), e);
            return ApiResultDTO.error(ERROR_RSCODE, e.getMessage());
        } catch (Exception e) {
            logger.error("验证文件生成和上传状态发生异常：", e);
            return ApiResultDTO.error(ERROR_RSCODE, "获取当前区划文件生成和上传状态失败！");
        }
    }

    /**
     * 生成并导出银行数据
     * @param tokenId
     * @return
     */
    @GetMapping("/generateAndExportBankData")
    public ApiResultDTO generateAndExportBankData(@RequestHeader("X-Token") String tokenId, HttpServletResponse response){
        try{
            UserDTO userDTO = getUser(tokenId);
            //添加操作日志
            OperrateLogs operrateLogs= new OperrateLogs();
            operrateLogs.setMofDivCode(userDTO.getProvince());
            operrateLogs.setTokenId(tokenId);
            operrateLogs.setUserAgencyId(userDTO.getAgency());
            operrateLogs.setUeserName(userDTO.getName());
            operrateLogs.setOperateName("生成工资数据--生成银行数据--生成并导出银行数据");
            iOperrateLogsService.saveOperrateLogs(operrateLogs);

            String fileName = "银行数据.xls";
            fileName = new String(fileName.getBytes(), StandardCharsets.UTF_8);
            response.addHeader("Content-Disposition", "filename=" + fileName);
            OutputStream outputStream = response.getOutputStream();
            generateBankDataService.generateBankDataService(userDTO, outputStream);
            return ApiResultDTO.success();
        }catch(AppRuntimeException e){
            logger.error(e.getMessage(), e);
            return ApiResultDTO.error(ERROR_RSCODE, "生成银行数据失败！");
        } catch (Exception e) {
            logger.error("生成并导出银行数据发生异常：", e);
            return ApiResultDTO.error(ERROR_RSCODE, "生成银行数据失败！");
        }
    }


    @GetMapping("/queryGenerateBankGetMessage")
    public ApiResultDTO queryGenerateBankGetMessage(@RequestHeader("X-Token") String tokenid,
                                                  @RequestParam Map<String,Object> queryForm){
        try {
            UserDTO userDTO = getUser(tokenid);
            //agencyCount 单位数,personCount 人员数,sumRealSalary 金额总值
            List<Map<String, Object>> requestList = generateBankDataService.getGenerateMessage( queryForm, userDTO);
            return ApiResultDTO.success(requestList);
        } catch (Exception e) {
            logger.error(e.getMessage(), e);
            return ApiResultDTO.error(ERROR_RSCODE, "查询数据异常");
        }
    }

}
